﻿using System;
using System.IO;

namespace ActiveStory.IO
{
    public static class FileManager
    {
        private static string _projectPath;
        /// <summary>
        /// The path to the project. Must be set as soon as the application is run.
        /// </summary>
        public static String ProjectPath
        {
            get
            {
                return _projectPath;
            }
            set
            {
                _projectPath = value;
            }
        }

        /// <summary>
        /// Copies a given file to the project's folder given the absolute path.
        /// The file can then be referenced using its relative path.
        /// Returns the absolute path to the copy of the resource.
        /// Overwrites any existing file of the same name.
        /// Must be done for any image added to the project. Images will automatically be 
        /// converted to the appropriate format for ActiveStory.
        /// </summary>
        /// <param name="sourceFilename">The absolute path to the file to be added to the project.</param>
        /// <param name="isImage">Indicates whether the file is an image. If so it will automatically be converted to the image format
        /// used by ActiveStory.</param>
        /// <returns>The absolute path to the copy of the resource.</returns>
        public static string CopyToProject(String sourceFilename, bool isImage)
        {
            if (!isImage)
            {
                File.Copy(sourceFilename, GetAbsolutePath(Path.GetFileName(sourceFilename)), true);
            }
            else
            {
                if (Path.GetExtension(sourceFilename) != ActiveStoryApplication.ImageFileExtension)
                {
                    System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(sourceFilename);
                    bitmap.Save(Path.ChangeExtension(GetAbsolutePath(Path.GetFileNameWithoutExtension(sourceFilename)), ".png"), ActiveStoryApplication.SavedImageFormat);
                }
                else
                    File.Copy(sourceFilename, GetAbsolutePath(Path.GetFileName(sourceFilename)), true);
            }
            return GetAbsolutePath(Path.GetFileName(sourceFilename));
        }

        /// <summary>
        /// Deletes a file from the project given the relative path.
        /// </summary>
        /// <param name="filename">The relative path to the file.</param>
        public static void DeleteFromProject(String filename)
        {
            string absolutePath = GetAbsolutePath(filename);
            if (!File.Exists(absolutePath))
                return;
            File.Delete(absolutePath);
        }

        /// <summary>
        /// Copies all the contents of the source directory to the target directory recursively.
        /// Directories must be the absolute paths.
        /// </summary>
        /// <param name="sourceDirectory"></param>
        /// <param name="targetDirectory"></param>
        public static void CopyDirectory(string sourceDirectory, string targetDirectory)
        {
            if (!Directory.Exists(targetDirectory))
                Directory.CreateDirectory(targetDirectory);
            string[] files = Directory.GetFiles(sourceDirectory);
            foreach (string file in files)
            {
                string name = Path.GetFileName(file);
                string dest = Path.Combine(targetDirectory, name);
                File.Copy(file, dest, true);
            }
            string[] folders = Directory.GetDirectories(sourceDirectory);
            foreach (string folder in folders)
            {
                string name = Path.GetFileName(folder);
                string dest = Path.Combine(targetDirectory, name);
                CopyDirectory(folder, dest);
            }
        }

        /// <summary>
        /// Takes a relative path and returns the filename with 
        /// the appropriate path to the project appended to it, giving the absolute path to the file.
        /// Relative path must not start with '\'
        /// </summary>
        /// <param name="relativePath">Relative path to the file.</param>
        /// <returns></returns>
        public static String GetAbsolutePath(String relativePath)
        {
            return Path.Combine(_projectPath, relativePath);
        }

        /// <summary>
        /// Creates a Xaml filename given the project name and page number.
        /// Includes the appropriate extension.
        /// </summary>
        /// <param name="projectName">Project name.</param>
        /// <param name="pageNumber">Page number.</param>
        /// <returns></returns>
        public static string CreateXamlFileName(string projectName, int pageNumber)
        {
            if (pageNumber < 0 || projectName.Equals(String.Empty))
                throw new Exception("ActiveStoryApplication.CreateXamlFileName():Invalid projectName or pageNumber:" + projectName + ":" + pageNumber.ToString());
            return projectName + "-" + pageNumber + ActiveStoryApplication.XamlFileExtension;
        }

        /// <summary>
        /// Creates a thumbnail filename given the project name and page number.
        /// Includes the appropriate extension.
        /// </summary>
        /// <param name="projectName">Project name.</param>
        /// <param name="pageNumber">Page number.</param>
        /// <returns></returns>
        public static string CreateThumbnailFileName(string projectName, int pageNumber)
        {
            if (pageNumber < 0 || projectName.Equals(String.Empty))
                throw new Exception("ActiveStoryApplication.CreateThumbnailFileName():Invalid projectName or pageNumber:" + projectName + ":" + pageNumber.ToString());
            return projectName + "-" + pageNumber + ActiveStoryApplication.ImageFileExtension;
        }

        /// <summary>
        /// Creates a buttonToPageMap filename given the project name and page number.
        /// Includes the appropriate extension.
        /// </summary>
        /// <param name="projectName">Project name.</param>
        /// <param name="pageNumber">Page number.</param>
        /// <returns></returns>
        public static string CreateButtonMapFileName(string projectName, int pageNumber)
        {
            if (pageNumber < 0 || projectName.Equals(String.Empty))
                throw new Exception("ActiveStoryApplication.CreateButtonMapFileName():Invalid projectName or pageNumber:" + projectName + ":" + pageNumber.ToString());
            return projectName + "-" + pageNumber + ActiveStoryApplication.ButtonToPageMapFileExtension;
        }


        /// <summary>
        /// Creates a page filename given the project name and page number.
        /// Includes the appropriate extension.
        /// </summary>
        /// <param name="projectName">Project name.</param>
        /// <param name="pageNumber">Page number.</param>
        /// <returns></returns>
        public static string CreatePageFileName(string projectName, int pageNumber)
        {
            if (pageNumber < 0 || projectName.Equals(String.Empty))
                throw new Exception("ActiveStoryApplication.CreatePageFileName():Invalid projectName or pageNumber:" + projectName + ":" + pageNumber.ToString());
            return projectName + "-" + pageNumber + ActiveStoryApplication.PageFileExtension;
        }

        /// <summary>
        /// Creates a page lookup table filename given the project name.
        /// Includes the appropriate extension.
        /// </summary>
        /// <param name="projectName">Project name.</param>
        /// <returns></returns>
        public static string CreatePageLookupTableFileName(string projectName)
        {
            if (projectName.Equals(String.Empty))
                throw new Exception("ActiveStoryApplication.CreatePageLookupTableFileName():Invalid projectName:" + projectName);
            return projectName + ActiveStoryApplication.PageLookupTableFileExtension;
        }

        /// <summary>
        /// Creates a name for the project file given the project name and destination folder
        /// Returns an absolute path with the appropriate extension
        /// </summary>
        /// <param name="projectName">Project name.</param>
        /// <param name="destinationFolder">Destination folder.</param>
        /// <returns></returns>
        public static string CreateProjectFileName(string projectName, string destinationFolder)
        {
            return Path.Combine(destinationFolder, projectName + ActiveStoryApplication.ProjectFileExtension);
        }
    }
}
